/**
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 *   
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 */
package org.jiopi.ibean.kernel.util;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.jiopi.framework.ControlPanel;
import org.jiopi.ibean.kernel.context.ControlPanelImpl;

/**
 * 
 * 使用Java反射机制进行对象的访问
 * 
 * <P>
 * 使用字符串指定类型时,基本类型直接使用 int long 等定义,数组使用 int[] 或 类名[] 如 java.lang.String[]
 * </P> 
 * <P>
 * v0.2:引入ControlPanel模式支持,允许参数传递ControlPanel,返回值接受ControlPanel
 * v0.1:实现一般java对象的反射调用
 * </P>
 * 
 * @version 0.2 , 2010.4.20
 * @since iBeanKernel0.1 , 2010.4.20
 *
 */
public class ObjectAccessor {
	
    
    /**
     * 使用给定的类加载器将制定的类名数组变更为类数组
     * @param classNames
     * @param cl
     * @return
     * @since iBeanKernel0.1 , 2010.4.21
     */
    private static Class<?>[] toClass(Object[] classNames,ClassLoader cl){
    	if(classNames == null) throw new IllegalArgumentException("classNames can't be NULL!");
    	Class<?>[] classes = new Class<?>[classNames.length];
    	for(int i=0;i<classNames.length;i++){
    		Object className = classNames[i];
    		if( className instanceof String ) classes[i] = loadClass((String)className,cl);
    		else if ( className instanceof Class )  classes[i] = (Class<?>) className;
    		else throw new IllegalArgumentException("classNames must be Class or String! But got "+className.getClass().getName());
    	}
    	return classes;
	}
    private final static Map<String, Class<?>> primitiveClassMap;
	static {
		Map<String,Class<?>> tmp = new HashMap<String, Class<?>>();
		tmp.put("short", short.class );
		tmp.put("int",  int.class);
		tmp.put("char",  char.class);
		tmp.put("long",  long.class);
		tmp.put("boolean",  boolean.class);
		tmp.put("float",  float.class);
		tmp.put("double",  double.class);
		tmp.put("byte",  byte.class);
		primitiveClassMap = Collections.unmodifiableMap( tmp );
	}
	private final static Map<String, String> primitiveArrayClassMap;
	static {
		Map<String,String> tmp = new HashMap<String, String>();
		tmp.put("short[]", "[S" );
		tmp.put("int[]",  "[I");
		tmp.put("char[]",  "[C");
		tmp.put("long[]",  "[L");
		tmp.put("boolean[]",  "[Z");
		tmp.put("float[]",  "[F");
		tmp.put("double[]",  "[D");
		tmp.put("byte[]",  "[B");
		primitiveArrayClassMap = Collections.unmodifiableMap( tmp );
	}
    public static Class<?> loadClass(String className,ClassLoader cl){
    	if(primitiveClassMap.containsKey(className))return primitiveClassMap.get(className);
    	else if(primitiveArrayClassMap.containsKey(className)) className = primitiveArrayClassMap.get(className);
    	else if(className.endsWith("[]")){
    		className = "[L"+className.substring(0,className.length()-2)+";";
    	}
    	if(cl==null){
    		cl = Thread.currentThread().getContextClassLoader();
    	}
    	try {
			return Class.forName(className,false,cl);
		} catch (ClassNotFoundException e) {
			throw new RuntimeException(e);
		}
    }
    
    
	
	/**
	 * 访问指定的public成员变量
	 * @param obj
	 * @param varName
	 * @param returnType
	 * @return
	 * @since iBeanKernel0.1 , 2010.4.21
	 */
	public static <T> T variable(Object obj,String varName,Class<T> returnType){
		return variable(obj,varName,returnType,true);
	}
	
	public static Class<?> variableClass(Object obj,String varName){
		return variableClass(obj,varName,true);
	}
	
	protected static Class<?> variableClass(Object obj,String varName,boolean isPublic){
		Object variableObject = obj;
		Class<?> objectClass = obj.getClass();
		if(obj instanceof Class){
			objectClass = (Class<?>)variableObject;
			variableObject = null;
		}
		Field f = getProperField(objectClass,varName,variableObject == null,isPublic);
		return f.getType();
	}
	
	protected static <T> T variable(Object obj,String varName,Class<T> returnType,boolean isPublic){
		Object variableObject = obj;
		Class<?> objectClass = obj.getClass();
		if(obj instanceof Class){
			objectClass = (Class<?>)variableObject;
			variableObject = null;
		}
		Field f = getProperField(objectClass,varName,variableObject == null,isPublic);
		Object rt;
		try {
			rt = f.get(variableObject);
		}catch (IllegalAccessException e) {
			throw new RuntimeException(e);
		}
		return processReturnValue(rt,returnType);
	}
	
	/**
	 * 设置成员变量的值
	 * @param obj
	 * @param varName
	 * @param newObj
	 */
	public static void setVariable(Object obj,String varName,Object newValue){
		setVariable(obj,varName,newValue,true);
	}
	
	protected static void setVariable(Object obj,String varName,Object newValue,boolean isPublic){
		Object variableObject = obj;
		Class<?> objectClass = obj.getClass();
		if(obj instanceof Class){
			objectClass = (Class<?>)variableObject;
			variableObject = null;
		}
		Field f = getProperField(objectClass,varName,variableObject == null,isPublic);
		try {
			f.set(variableObject, newValue);
		}catch (IllegalAccessException e) {
			throw new RuntimeException(e);
		}
	}
	
	private static Field getProperField(Class<?> c, String name, boolean isStatic,boolean isPublic){
		Field f = null;
		try {
			if(isPublic) f = c.getField( name );
			else f = c.getDeclaredField(name);
			int mod = f.getModifiers();
			if( isStatic&&!Modifier.isStatic( mod ) ) f = null;
			else if(!isPublic && !Modifier.isPublic(mod)) f.setAccessible(true);
		}catch (NoSuchFieldException e) {
		}
		if(f==null){
			throw new RuntimeException(new NoSuchFieldException("no"+isPublicToString(isPublic)+isStaticToString(isStatic)+" variable : "+c.getName() + "." + name));
		}
		return f;
	}
	
	
	/**
	 * 使用public构造器生成对象
	 * @param c
	 * @param parameterTypes
	 * @param args
	 * @return
	 * @since iBeanKernel0.1 , 2010.4.21
	 */
	public static <T> T strictConstructor(Class<?> c,Object[] parameterTypes,Class<T> returnType,Object... args){
		return strictConstructor(c,returnType,true,parameterTypes,args);
	}
	
	protected static <T> T strictConstructor(Class<?> c,Class<T> returnType,boolean isPublic,Object[] parameterTypes,Object... args){
		args = filterArgs(args);
		Class<?>[] classTypes = toClass(parameterTypes,c.getClassLoader());
		Constructor<?> con;
		try {
			if(isPublic){
				con = c.getConstructor(classTypes);
			}else{
				con = c.getDeclaredConstructor(classTypes);
			}
			
		}catch (NoSuchMethodException e1) {
			throw new RuntimeException(new NoSuchMethodException("no public constructor : "+c.getName()+argumentTypesToString(classTypes)));
		}
		try {
			return processReturnValue(con.newInstance( args ),returnType);
		} catch (InstantiationException e) {
			throw new RuntimeException(e);
		} catch (IllegalAccessException e) {
			throw new RuntimeException(e);
		} catch (InvocationTargetException e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 通过给定参数自动匹配public
	 * @param c
	 * @param args
	 * @return
	 * @since iBeanKernel0.1 , 2010.4.21
	 */
	public static <T> T constructor(Class<?> c,Class<T> returnType,Object... args){
		return constructor(c,returnType,true,args);
	}
	

	protected static <T> T constructor(Class<?> c,Class<T> returnType,boolean isPublic,Object... args){
		args = filterArgs(args);
		Constructor<?> con = null;
		Class<?>[] argTypes = getArgTypes( args );
		Class<?>[] constructorTypes;
		int matchScore = NOT_MATCH,score;
		Constructor<?>[] constructors = null;
		if(isPublic) constructors = c.getConstructors();
		else constructors = c.getDeclaredConstructors();
		
		for(Constructor<?> constructor:constructors){
			constructorTypes = constructor.getParameterTypes();
			boolean isVarArgs = constructor.isVarArgs();
			score = testMatch(argTypes,constructorTypes,isVarArgs);
			if(isVarArgs)score-=1;
			if(score != NOT_MATCH && score>matchScore){
				matchScore = score;
				con = constructor;
			}
		}
		if(con==null){
			throw new RuntimeException(new NoSuchMethodException("no"+isPublicToString(isPublic)+" constructor : "+c.getName()+argumentTypesToString(argTypes)));
		}
		
		if(con.isVarArgs()&&args!=null){
			args = transVarArgs(con.getParameterTypes(),args);
		}
		try {
			if(!isPublic && !Modifier.isPublic(con.getModifiers()))con.setAccessible(true);
			return processReturnValue(con.newInstance( args ),returnType);
		} catch (InstantiationException e) {
			throw new RuntimeException(e);
		} catch (IllegalAccessException e) {
			throw new RuntimeException(e);
		} catch (InvocationTargetException e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 
	 * 使用明确的参数表类型动态调用方法
	 * 
	 * @param obj
	 * @param methodName
	 * @param returnType
	 * @param parameterTypes
	 * @param args
	 * @return
	 * @since iBeanKernel0.1 , 2010.4.21
	 */
	public static <T> T strictMethod(Object obj,String methodName,Class<T> returnType,Object[] parameterTypes,Object... args){
		return strictMethod(obj,methodName,returnType,parameterTypes,true,args);
	}
	
	public static boolean containsStrictStaticMethod(Class<?> c,String methodName,Object[] parameterTypes){
		Class<?>[] classTypes = toClass(parameterTypes,c.getClassLoader());
		Method m = null;
		try {
			m = c.getMethod(methodName, classTypes);
		}catch (Exception e) {
		}
		return m!=null;
	}
	
	protected static <T> T strictMethod(Object obj,String methodName,Class<T> returnType,Object[] parameterTypes,boolean isPublic,Object... args){
		args = filterArgs(args);
		Object methodObject = obj;
		Class<?> objectClass = obj.getClass();
		if(obj instanceof Class){
			objectClass = (Class<?>)methodObject;
			methodObject = null;
		}
		boolean isStatic = methodObject == null;
		
		Class<?>[] classTypes = toClass(parameterTypes,objectClass.getClassLoader());
		
		Method m = null;
		try {
			if(isPublic)m = objectClass.getMethod(methodName, classTypes);
			else m = objectClass.getDeclaredMethod(methodName, classTypes);
		}catch (NoSuchMethodException e) {
			throw new RuntimeException(new NoSuchMethodException("no"+isPublicToString(isPublic)+isStaticToString(isStatic)+" method : "+objectClass.getName() + "." + methodName + argumentTypesToString(classTypes)));
		}
		
		int mod = m.getModifiers();
		if(isStatic&&!Modifier.isStatic(mod)){
			throw new RuntimeException(new NoSuchMethodException("no"+isPublicToString(isPublic)+isStaticToString(isStatic)+" method : "+objectClass.getName() + "." + methodName + argumentTypesToString(classTypes)));
		}
		if(!isPublic && !Modifier.isPublic(mod)) m.setAccessible(true);
		try {
			return processReturnValue(m.invoke(methodObject, args),returnType);
		} catch (IllegalAccessException e) {
			throw new RuntimeException(e);
		} catch (InvocationTargetException e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 执行给定对象的方法
	 * 
	 * <P>
	 * 如果obj是一个 类对象(Class对象的子类),则认为是执行类的静态方法
	 * </P>
	 * @param obj
	 * @param methodName
	 * @param returnType
	 * @param args
	 * @return
	 * @since iBeanKernel0.1 , 2010.4.20
	 */
	public static <T> T method(Object obj,String methodName,Class<T> returnType,Object... args){
		return method(obj,methodName,returnType,true,args);
	}
	
	public static boolean containsStaticMethod(Class<?> c,String methodName,Object... args){
		Method m = null;
		try{
			m = getProperMethod(c,methodName,true,true,args);
		}catch(Exception e){
			
		}
		return m!=null;
	}
	
	protected static <T> T method(Object obj,String methodName,Class<T> returnType,boolean isPublic,Object... args){
		args = filterArgs(args);
		Object methodObject = obj;
		Class<?> objectClass = obj.getClass();
		if(obj instanceof Class){
			objectClass = (Class<?>)methodObject;
			methodObject = null;
		}
		Method m = getProperMethod(objectClass,methodName,methodObject==null,isPublic,args);
		if(m.isVarArgs()&&args!=null) args = transVarArgs(m.getParameterTypes(),args);
		else if(args == null) args = new Object[]{null};
		try {
			return processReturnValue(m.invoke(methodObject, args),returnType);
		} catch (IllegalAccessException e) {
			throw new RuntimeException(e);
		} catch (InvocationTargetException e) {
			throw new RuntimeException(e);
		}
	}
	private static Object[] transVarArgs(Class<?>[] varTypes,Object... args){
		Object[] newArgs = new Object[varTypes.length];
		Object[] varArgs = null;
		int varArgIndex = 0;
		boolean notChecked = true;
		for(int i=0;i<args.length;i++){
			if((i+1==varTypes.length)){//分界点
				varArgs = (Object[]) Array.newInstance(varTypes[i].getComponentType(), args.length-varTypes.length+1);
			}else if( i< varTypes.length ){
				newArgs[i]= args[i];
			}
			if(varArgs!=null){
				if(notChecked && args[i]!=null && args[i].getClass().getComponentType()!=null){
					notChecked = false;
					varArgs = (Object[]) args[i];
					break;
				}
				varArgs[varArgIndex++]=args[i];
			}
		}
		newArgs[varTypes.length-1]=varArgs;
		return newArgs;
	}
	
	
	private final static int NOT_MATCH = 0;
	private final static int MATCH = 1000;
	private final static int MAY_MATCH = 2;
	private static Method getProperMethod(Class<?> c,String methodName,boolean isStatic,boolean isPublic,Object... args){
		Method m = null;
		//获取参数类型
		Class<?>[] argTypes = getArgTypes( args );
		Method[] methods = MethodManager.getMethods( c, methodName, argTypes.length ,true);
		m = getProperMethod(methods,isStatic,false,argTypes);
		if(m==null){//尝试查找变参函数
			methods = MethodManager.getMethods( c, methodName, -1 ,true);
			m = getProperMethod(methods,isStatic,true,argTypes);
		}
		if(m==null&&!isPublic){
			methods = MethodManager.getMethods( c, methodName, argTypes.length ,false);
			m = getProperMethod(methods,isStatic,false,argTypes);
			if(m==null){//尝试查找变参函数
				methods = MethodManager.getMethods( c, methodName, -1 ,false);
				m = getProperMethod(methods,isStatic,true,argTypes);
			}
			if(m!=null) m.setAccessible(true);
		}
		
		if(m==null){
			throw new RuntimeException(new NoSuchMethodException("no"+isPublicToString(isPublic)+isStaticToString(isStatic)+" method : "+c.getName() + "." + methodName + argumentTypesToString(argTypes)));
		}
		return m;
	}
	private static Method getProperMethod(Method[] methods,boolean isStatic,boolean isVarArgs,Class<?>[] argTypes){
		if(methods == null )return null;
		Method m = null;
		Class<?>[] methodTypes;
		int matchScore = NOT_MATCH,score,mod;
		for( Method method:methods ) {
			mod = method.getModifiers();
			if( !isStatic||isStatic&&Modifier.isStatic( mod ) ) {
				methodTypes = method.getParameterTypes();
				score = testMatch(argTypes,methodTypes,isVarArgs);
				if(score != NOT_MATCH && score>matchScore){//匹配
					matchScore = score;
					m = method;
				}
			}
		}
		return m;
	}
	private static int testMatch(Class<?>[] argTypes, Class<?>[] paramTypes,boolean isVarArgs){
		if(!isVarArgs && paramTypes.length!=argTypes.length)return NOT_MATCH;
		Class<?> arg, param=null;
		int total = MAY_MATCH, score;
		for( int i=0;i<argTypes.length;i++ ) {
			arg = argTypes[i];
			if(isVarArgs && (i+1)==paramTypes.length){
				if(arg.getComponentType()==null)param = paramTypes[i].getComponentType();
				else{
					score = testMatch(arg,paramTypes[i]);
					if(score==NOT_MATCH)return NOT_MATCH;
					return total + score;
				}
			}
			else if( i< paramTypes.length ){
				param = paramTypes[i];
			}
			score = testMatch(arg,param);
			if(score==NOT_MATCH) return NOT_MATCH;
			total+=score;
		}
//		System.out.println( "args:" + argumentTypesToString( argTypes )
//		+ ", params:" + argumentTypesToString( paramTypes ) 
//		+ ",\n returned " + total );
		return total;
	}
	public static int testMatch(Class<?> argType,Class<?> paramType){
		if(argType==null){
			if(paramType.isPrimitive()) return NOT_MATCH;
			else return MAY_MATCH;
		}
		if( !paramType.isPrimitive() ) {
			if( argType.equals( paramType ) ) {
				return MATCH;
			} else if( paramType.isAssignableFrom( argType ) ) {
				return MAY_MATCH;
			} else {
				return NOT_MATCH;
			}
		} else {
			return primitiveEquals( argType, paramType );
		}
	}
	private final static Map<Class<?>, Class<?>> primitiveMap;
	static {
		// 设置基本类型和封装类
		Map<Class<?>,Class<?>> tmp = new HashMap<Class<?>, Class<?>>();
		tmp.put( short.class, Short.class );
		tmp.put( int.class, Integer.class );
		tmp.put( char.class, Character.class );
		tmp.put( long.class, Long.class );
		tmp.put( boolean.class, Boolean.class );
		tmp.put( float.class, Float.class );
		tmp.put( double.class, Double.class );
		tmp.put( byte.class, Byte.class );
		primitiveMap = Collections.unmodifiableMap( tmp );
	}
	private static int primitiveEquals( Class<?> wrapper, Class<?> prim ) {
		if( prim.equals( wrapper ) ) {
			return MATCH;
		}
		if( primitiveMap.get( prim ).equals( wrapper ) ) {
			return MAY_MATCH;
		}
		return NOT_MATCH;
	}
	
	private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class[1];
	private static Class<?>[] getArgTypes(Object... args){
		if(args == null)return EMPTY_CLASS_ARRAY;
		int len = args.length;
		Class<?>[] types = new Class[ len ];
		for(int i=0;i<len;i++){
			if( args[i]!=null ) types[i] = args[i].getClass();
		}
		return types;
	}
	
	
	@SuppressWarnings("unchecked")
	public static <T> T processReturnValue( Object value ,Class<T> returnType) {
		if(value==null || returnType==null || returnType != ControlPanel.class)return (T)value;
		else if(value.getClass().getClassLoader()!=null)return (T)new ControlPanelImpl(value);
		else return (T)value;
	}
	
	private static Object[] filterArgs( Object[] args ) {
		if( args==null ) return null;
		int len = args.length;
		Object[] ret = new Object[ len ];
		for( int i=0;i<len;i++ ) {
			ret[i] = filterArg( args[i] );
		}
		return ret;
	}
	
	public static Object filterArg( Object arg ) {
		if( arg!=null && arg instanceof ControlPanelImpl) return ((ControlPanelImpl)arg).wrapped;
		return arg;
	}
	
	private static class MethodManager{
		private static Map<Class<?>,Map<String,Method[]>> publicClassMethodCache = new HashMap<Class<?>,Map<String,Method[]>>();
		private static Map<Class<?>,Map<String,Method[]>> otherClassMethodCache = new HashMap<Class<?>,Map<String,Method[]>>();
		
		public static Method[] getMethods( Class<?> c, String name, int argLen ,boolean isPublic){
			Map<String,Method[]> classMethods = getClassMethods(c,isPublic);
			return classMethods.get( getMethodKey( name, argLen) );
		}
		
		private static Map<String,Method[]> getClassMethods(Class<?> c,boolean isPublic){
			Map<String,Method[]> classMethods = null;
			
			Map<Class<?>,Map<String,Method[]>> needCache = publicClassMethodCache;
			if(!isPublic) needCache = otherClassMethodCache;
			
			synchronized(publicClassMethodCache){
				classMethods = needCache.get(c);
			}
			if(classMethods == null){
				synchronized(c){
					synchronized(publicClassMethodCache){
						classMethods = needCache.get(c);
					}
					if(classMethods == null){
						Map<String, List<Method>> mMap = new LinkedHashMap<String, List<Method>>();
						Method[] allMethods = null;
						if(isPublic) allMethods = c.getMethods();
						else allMethods = c.getDeclaredMethods();
						for( Method m:allMethods) {
							if(!isPublic && Modifier.isPublic(m.getModifiers())) continue;
							int typesLen = m.getParameterTypes().length;
							if(m.isVarArgs())typesLen = -1;
							String mKey = getMethodKey( m.getName(), typesLen);
							List<Method> methods = mMap.get( mKey );
							if( methods==null ) {
								methods = new ArrayList<Method>();
								mMap.put(mKey, methods);
							}
							methods.add(m);
						}
						classMethods = new HashMap<String,Method[]>();
						for( Map.Entry<String, List<Method>> en:mMap.entrySet() ) {
							classMethods.put( en.getKey(), en.getValue().toArray( new Method[]{} ) );
						}
						synchronized(publicClassMethodCache){
							needCache.put(c, classMethods);
						}
					}
				}
			}
			
			return classMethods;
		}
		private static String getMethodKey( String methodName, int argLen) {
			return argLen + methodName;
		}
	}
	
	private static String isStaticToString(boolean isStatic){
		if(isStatic) return " static";
		return "";
	}
	
	private static String isPublicToString(boolean isPublic){
		if(isPublic) return " public";
		return "";
	}
	
	private static String argumentTypesToString(Class<?>[] argTypes) {
        StringBuilder buf = new StringBuilder();
        buf.append("(");
        if (argTypes != null) {
            for (int i = 0; i < argTypes.length; i++) {
                if (i > 0) {
                    buf.append(", ");
                }
		Class<?> c = argTypes[i];
		buf.append((c == null) ? "null" : c.getName());
            }
        }
        buf.append(")");
        return buf.toString();
    }
	
	/**
	 * 
	 * 覆盖ObjectAccessor的 variable constructor method 方法,访问时不做只访问public的限制
	 * ,
	 * 
	 * @version 0.1 , 2010.4.21
	 * @since iBeanKernel0.1 , 2010.4.21
	 */
	public static class Accessible extends ObjectAccessor{
		
		public static Class<?> variableClass(Object obj,String varName){
			return variableClass(obj,varName,false);
		}
			
		
		/**
		 * 访问指定的成员变量
		 * @param obj
		 * @param varName
		 * @param returnType
		 * @return
		 * @since iBeanKernel0.1 , 2010.4.21
		 */
		public static <T> T variable(Object obj,String varName,Class<T> returnType){
			return variable(obj,varName,returnType,false);
		}
		
		/**
		 * 设置成员变量的值
		 * @param obj
		 * @param varName
		 * @param newObj
		 */
		public static void setVariable(Object obj,String varName,Object newValue){
			setVariable(obj,varName,newValue,false);
		}
		
		/**
		 * 使用构造器生成对象
		 * @param c
		 * @param parameterTypes
		 * @param args
		 * @return
		 * @since iBeanKernel0.1 , 2010.4.21
		 */
		public static <T> T strictConstructor(Class<?> c,Class<T> returnType,Object[] parameterTypes,Object... args){
			return strictConstructor(c,returnType,false,parameterTypes,args);
		}
	
		/**
		 * 通过给定参数自动匹配
		 * @param c
		 * @param args
		 * @return
		 * @since iBeanKernel0.1 , 2010.4.21
		 */
		public static <T> T constructor(Class<?> c,Class<T> returnType,Object... args){
			return constructor(c,returnType,false,args);
		}
		
		/**
		 * 
		 * 使用明确的参数表类型动态调用方法
		 * 
		 * @param obj
		 * @param methodName
		 * @param returnType
		 * @param parameterTypes
		 * @param args
		 * @return
		 * @since iBeanKernel0.1 , 2010.4.21
		 */
		public static <T> T strictMethod(Object obj,String methodName,Class<T> returnType,Object[] parameterTypes,Object... args){
			return strictMethod(obj,methodName,returnType,parameterTypes,false,args);
		}
		
		/**
		 * 执行给定对象的方法
		 * 
		 * <P>
		 * 如果obj是一个 类对象(Class对象的子类),则认为是执行类的静态方法
		 * </P>
		 * @param obj
		 * @param methodName
		 * @param returnType
		 * @param args
		 * @return
		 * @since iBeanKernel0.1 , 2010.4.20
		 */
		public static <T> T method(Object obj,String methodName,Class<T> returnType,Object... args){
			return method(obj,methodName,returnType,false,args);
		}
	}
}
